package com.acmen.easyapi.util;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

/**
 * 注解工具类
 * @author acmen
 */
public class AnnotationUtil {
    /**
     * 获取注解类型
     *
     * @param annotations
     * @param clazz
     * @param <T>
     * @return
     */
    public static  <T> T getAnnotation(List<Annotation> annotations, Class<T> clazz) {
        for (Annotation annotation : annotations) {
            if (annotation.annotationType().equals(clazz)) {
                return (T) annotation;
            }
        }
        return null;
    }
    public static List<List<Annotation>> getParameterAnnotations(Method method) {
        List<Method> methods = getMethodsFromInterfaces(method.getDeclaringClass().getInterfaces(),method);
        methods.add(method);
        List<List<Annotation>> parameterAnnotations = new ArrayList<>();
        for(int i =0;i<method.getParameters().length;i++){
            parameterAnnotations.add(new ArrayList<>());
        }
        for(Method m : methods){
            for(int i =0;i<m.getParameters().length;i++){
                Annotation[] annotations = m.getParameterAnnotations()[i];
                for(Annotation a : annotations){
                    parameterAnnotations.get(i).add(a);
                }
            }
        }
        return parameterAnnotations;
    }

    /**
     * aqbc
     * @param interfaces
     * @param method
     * @return
     */
    private static List<Method> getMethodsFromInterfaces(Class[] interfaces, Method method) {
        List<Method> methods = new ArrayList<>();
        String code1 = getMethodCode(method);
        for(Class interface1 : interfaces){
            while (interface1!=null&&!interface1.equals(Object.class)){
                for(Method m : interface1.getDeclaredMethods()){
                    String code2 = getMethodCode(m);
                    if(code1.equals(code2)){
                        methods.add(m);
                    }
                }
                interface1 = interface1.getSuperclass();
            }
        }
        return methods;
    }

    private static String getMethodCode(Method method) {
        String str = method.getName();
        for(Type type : method.getParameterTypes()){
            str += type.getTypeName();
        }
        return str;
    }
}
